<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name=Generator content="Microsoft Word 14 (filtered)">

<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:宋体;
	panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
	{font-family:黑体;
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:黑体;
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:方正小标宋简体;}
@font-face
	{font-family:"\@黑体";
	panose-1:2 1 6 9 6 1 1 1 1 1;}
@font-face
	{font-family:"\@宋体";
	panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
	{font-family:"\@方正小标宋简体";}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
h1
	{mso-style-link:"标题 1 Char";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:7.2pt;
	text-align:center;
	text-indent:-7.2pt;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
h2
	{mso-style-link:"标题 2 Char";
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:0cm;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:0cm;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h3
	{mso-style-link:"标题 3 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:0cm;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h4
	{mso-style-link:"标题 4 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:28.8pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.8pt;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
h5
	{mso-style-link:"标题 5 Char";
	margin-top:14.0pt;
	margin-right:0cm;
	margin-bottom:14.5pt;
	margin-left:36.0pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-36.0pt;
	line-height:156%;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:宋体;
	font-weight:bold;}
h6
	{mso-style-link:"标题 6 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:43.2pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-43.2pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.MsoHeading7, li.MsoHeading7, div.MsoHeading7
	{mso-style-link:"标题 7 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:50.4pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-50.4pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoHeading8, li.MsoHeading8, div.MsoHeading8
	{mso-style-link:"标题 8 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:57.6pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-72.0pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";}
p.MsoHeading9, li.MsoHeading9, div.MsoHeading9
	{mso-style-link:"标题 9 Char";
	margin-top:12.0pt;
	margin-right:0cm;
	margin-bottom:3.2pt;
	margin-left:64.8pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-79.2pt;
	line-height:133%;
	page-break-after:avoid;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.MsoIndex1, li.MsoIndex1, div.MsoIndex1
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:10.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex2, li.MsoIndex2, div.MsoIndex2
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex3, li.MsoIndex3, div.MsoIndex3
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:31.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex4, li.MsoIndex4, div.MsoIndex4
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex5, li.MsoIndex5, div.MsoIndex5
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:52.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex6, li.MsoIndex6, div.MsoIndex6
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:63.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex7, li.MsoIndex7, div.MsoIndex7
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:73.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex8, li.MsoIndex8, div.MsoIndex8
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:84.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoIndex9, li.MsoIndex9, div.MsoIndex9
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:94.5pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-10.5pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc1, li.MsoToc1, div.MsoToc1
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoToc2, li.MsoToc2, div.MsoToc2
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc3, li.MsoToc3, div.MsoToc3
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoToc4, li.MsoToc4, div.MsoToc4
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:31.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc5, li.MsoToc5, div.MsoToc5
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc6, li.MsoToc6, div.MsoToc6
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:52.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc7, li.MsoToc7, div.MsoToc7
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:63.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc8, li.MsoToc8, div.MsoToc8
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:73.5pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoToc9, li.MsoToc9, div.MsoToc9
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:84.0pt;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
	{mso-style-link:"脚注文本 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
	{mso-style-link:"批注文字 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoHeader, li.MsoHeader, div.MsoHeader
	{mso-style-link:"页眉 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	layout-grid-mode:char;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoFooter, li.MsoFooter, div.MsoFooter
	{mso-style-link:"页脚 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.MsoIndexHeading, li.MsoIndexHeading, div.MsoIndexHeading
	{mso-style-name:"索引标题\,索引类目\,索引类目1\,索引类目2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.MsoTof, li.MsoTof, div.MsoTof
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
span.MsoFootnoteReference
	{vertical-align:super;}
p.MsoList, li.MsoList, div.MsoList
	{margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoList2, li.MsoList2, div.MsoList2
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoList4, li.MsoList4, div.MsoList4
	{margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.MsoDate, li.MsoDate, div.MsoDate
	{mso-style-link:"日期 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:5.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
a:link, span.MsoHyperlink
	{mso-style-name:"超链接\,超级链接";
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;}
p
	{mso-style-name:"普通\(网站\)\,普通 \(Web\)\,普通 \(Web\)1\,普通 \(Web\)2\,普通 \(Web\)3";
	margin-right:0cm;
	margin-left:0cm;
	font-size:12.0pt;
	font-family:宋体;}
pre
	{mso-style-name:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
	mso-style-link:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:宋体;}
tt
	{font-family:黑体;}
p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
	{mso-style-link:"批注主题 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.5pt;
	font-family:宋体;
	font-weight:bold;}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
	{mso-style-link:"批注框文本 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:9.0pt;
	font-family:宋体;}
p.1, li.1, div.1
	{mso-style-name:样式1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.a, li.a, div.a
	{mso-style-name:代码程序;
	mso-style-link:"代码程序 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
span.Char
	{mso-style-name:"代码程序 Char";
	mso-style-link:代码程序;
	font-family:宋体;}
p.a0, li.a0, div.a0
	{mso-style-name:图说明;
	mso-style-link:"图说明 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.Char0
	{mso-style-name:"图说明 Char";
	mso-style-link:图说明;
	font-family:宋体;}
p.0, li.0, div.0
	{mso-style-name:封面0;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.10, li.10, div.10
	{mso-style-name:封面1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.11, li.11, div.11
	{mso-style-name:非标题1;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.a1, li.a1, div.a1
	{mso-style-name:文本居中;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3CharChar, li.3CharChar, div.3CharChar
	{mso-style-name:"图中文字3 Char Char";
	mso-style-link:"图中文字3 Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharCharChar
	{mso-style-name:"图中文字3 Char Char Char";
	mso-style-link:"图中文字3 Char Char";
	font-family:宋体;}
p.post, li.post, div.post
	{mso-style-name:邮件post;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.3, li.3, div.3
	{mso-style-name:图中字体3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.3CharChar1CharCharChar
	{mso-style-name:"图中文字3 Char Char1 Char Char Char";
	font-family:宋体;}
span.3CharChar1CharChar
	{mso-style-name:"图中文字3 Char Char1 Char Char";
	font-family:宋体;}
p.5Char, li.5Char, div.5Char
	{mso-style-name:"图中文字5号 Char";
	mso-style-link:"图中文字5号 Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.5CharChar
	{mso-style-name:"图中文字5号 Char Char";
	mso-style-link:"图中文字5号 Char";
	font-family:宋体;}
p.5CharChar0, li.5CharChar0, div.5CharChar0
	{mso-style-name:"图中文字小5号 Char Char";
	mso-style-link:"图中文字小5号 Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
span.5CharCharChar
	{mso-style-name:"图中文字小5号 Char Char Char";
	mso-style-link:"图中文字小5号 Char Char";
	font-family:宋体;}
p.5Char0, li.5Char0, div.5Char0
	{mso-style-name:"图中文字小5号 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5, li.5, div.5
	{mso-style-name:图中文字小5号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.2, li.2, div.2
	{mso-style-name:代码程序2;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.20, li.20, div.20
	{mso-style-name:图说明2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.21, li.21, div.21
	{mso-style-name:文本居中2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3CharCharCharCharChar, li.3CharCharCharCharChar, div.3CharCharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char Char";
	mso-style-link:"图中文字3 Char Char Char Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharCharCharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char Char Char";
	mso-style-link:"图中文字3 Char Char Char Char Char";
	font-family:宋体;}
p.a2, li.a2, div.a2
	{mso-style-name:图居中;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.110, li.110, div.110
	{mso-style-name:"样式 标题 1 + 居中1";
	margin-right:0cm;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
span.1Char
	{mso-style-name:"标题 1 Char";
	mso-style-link:"标题 1";
	font-weight:bold;}
p.22, li.22, div.22
	{mso-style-name:"样式 列表 2 + 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.23, li.23, div.23
	{mso-style-name:列表2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.50, li.50, div.50
	{mso-style-name:图中文字5号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.111, li.111, div.111
	{mso-style-name:样式11;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.12, li.12, div.12
	{mso-style-name:代码程序1;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.13, li.13, div.13
	{mso-style-name:图说明1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.01, li.01, div.01
	{mso-style-name:封面01;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.112, li.112, div.112
	{mso-style-name:封面11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.113, li.113, div.113
	{mso-style-name:非标题11;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.14, li.14, div.14
	{mso-style-name:文本居中1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3Char1, li.3Char1, div.3Char1
	{mso-style-name:"图中文字3 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post1, li.post1, div.post1
	{mso-style-name:邮件post1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.31, li.31, div.31
	{mso-style-name:图中字体31;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char1, li.5Char1, div.5Char1
	{mso-style-name:"图中文字5号 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.5CharChar1, li.5CharChar1, div.5CharChar1
	{mso-style-name:"图中文字小5号 Char Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5Char10, li.5Char10, div.5Char10
	{mso-style-name:"图中文字小5号 Char1";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.51, li.51, div.51
	{mso-style-name:图中文字小5号1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.120, li.120, div.120
	{mso-style-name:样式12;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.02, li.02, div.02
	{mso-style-name:封面02;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.121, li.121, div.121
	{mso-style-name:封面12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.122, li.122, div.122
	{mso-style-name:非标题12;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.3Char2, li.3Char2, div.3Char2
	{mso-style-name:"图中文字3 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post2, li.post2, div.post2
	{mso-style-name:邮件post2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.32, li.32, div.32
	{mso-style-name:图中字体32;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char2, li.5Char2, div.5Char2
	{mso-style-name:"图中文字小5号 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.52, li.52, div.52
	{mso-style-name:图中文字小5号2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.3CharCharCharChar, li.3CharCharCharChar, div.3CharCharCharChar
	{mso-style-name:"图中文字3 Char Char Char Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.130, li.130, div.130
	{mso-style-name:样式13;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.30, li.30, div.30
	{mso-style-name:代码程序3;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:宋体;}
p.03, li.03, div.03
	{mso-style-name:封面03;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:36.0pt;
	font-family:宋体;
	font-weight:bold;}
p.131, li.131, div.131
	{mso-style-name:封面13;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:18.0pt;
	font-family:宋体;
	font-weight:bold;}
p.132, li.132, div.132
	{mso-style-name:非标题13;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.33, li.33, div.33
	{mso-style-name:文本居中3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.3Char3, li.3Char3, div.3Char3
	{mso-style-name:"图中文字3 Char3";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
p.post3, li.post3, div.post3
	{mso-style-name:邮件post3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:right;
	line-height:11.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.330, li.330, div.330
	{mso-style-name:图中字体33;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.5Char20, li.5Char20, div.5Char20
	{mso-style-name:"图中文字5号 Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.5CharChar2, li.5CharChar2, div.5CharChar2
	{mso-style-name:"图中文字小5号 Char Char2";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.5Char3, li.5Char3, div.5Char3
	{mso-style-name:"图中文字小5号 Char3";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.53, li.53, div.53
	{mso-style-name:图中文字小5号3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:9.0pt;
	font-family:宋体;}
p.3Char, li.3Char, div.3Char
	{mso-style-name:"图中文字3 Char";
	mso-style-link:"图中文字3 Char Char5";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:9.0pt;
	font-size:8.0pt;
	font-family:宋体;}
span.3CharChar5
	{mso-style-name:"图中文字3 Char Char5";
	mso-style-link:"图中文字3 Char";
	font-family:宋体;}
p.54, li.54, div.54
	{mso-style-name:图中文字小5紧密;
	margin:0cm;
	margin-bottom:.0001pt;
	line-height:9.0pt;
	text-autospace:ideograph-numeric;
	font-size:9.0pt;
	font-family:宋体;}
p.24, li.24, div.24
	{mso-style-name:居中2号粗宋体;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.15, li.15, div.15
	{mso-style-name:"样式 标题 1 + 居中";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.25, li.25, div.25
	{mso-style-name:"样式 标题 2 + 行距\: 单倍行距";
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:28.9pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.9pt;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.2Char
	{mso-style-name:"标题 2 Char";
	mso-style-link:"标题 2";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.34, li.34, div.34
	{mso-style-name:列表3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.35, li.35, div.35
	{mso-style-name:表3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.4, li.4, div.4
	{mso-style-name:图说明4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.40, li.40, div.40
	{mso-style-name:列表4;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.0pt;
	font-size:10.5pt;
	font-family:宋体;}
p.41, li.41, div.41
	{mso-style-name:表4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.55, li.55, div.55
	{mso-style-name:图说明5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.56, li.56, div.56
	{mso-style-name:列表5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.57, li.57, div.57
	{mso-style-name:表5;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.6, li.6, div.6
	{mso-style-name:列表6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.60, li.60, div.60
	{mso-style-name:表6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.61, li.61, div.61
	{mso-style-name:图说明6;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.7, li.7, div.7
	{mso-style-name:列表7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.70, li.70, div.70
	{mso-style-name:图说明7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.71, li.71, div.71
	{mso-style-name:表7;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.8, li.8, div.8
	{mso-style-name:列表8;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.9, li.9, div.9
	{mso-style-name:列表9;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.90, li.90, div.90
	{mso-style-name:图说明9;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.100, li.100, div.100
	{mso-style-name:列表10;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.101, li.101, div.101
	{mso-style-name:图说明10;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.114, li.114, div.114
	{mso-style-name:列表11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.115, li.115, div.115
	{mso-style-name:图说明11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.116, li.116, div.116
	{mso-style-name:表11;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.123, li.123, div.123
	{mso-style-name:列表12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.124, li.124, div.124
	{mso-style-name:图说明12;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.133, li.133, div.133
	{mso-style-name:图说明13;
	mso-style-link:"图说明13 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
span.13Char
	{mso-style-name:"图说明13 Char";
	mso-style-link:图说明13;
	font-family:宋体;}
p.134, li.134, div.134
	{mso-style-name:列表13;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.26, li.26, div.26
	{mso-style-name:附录2;
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:0cm;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.36, li.36, div.36
	{mso-style-name:附录3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.3Char0
	{mso-style-name:"标题 3 Char";
	mso-style-link:"标题 3";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.16, li.16, div.16
	{mso-style-name:附录1;
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.17, li.17, div.17
	{mso-style-name:附录表1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.42, li.42, div.42
	{mso-style-name:附录4;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.4Char
	{mso-style-name:"标题 4 Char";
	mso-style-link:"标题 4";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.a3, li.a3, div.a3
	{mso-style-name:附录图说明;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.27, li.27, div.27
	{mso-style-name:序标题2;
	margin-top:13.0pt;
	margin-right:0cm;
	margin-bottom:13.0pt;
	margin-left:28.8pt;
	text-align:justify;
	text-justify:inter-ideograph;
	text-indent:-28.8pt;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.a4, li.a4, div.a4
	{mso-style-name:参考标题;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.18, li.18, div.18
	{mso-style-name:索引标题1;
	margin-top:7.8pt;
	margin-right:0cm;
	margin-bottom:7.8pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.19, li.19, div.19
	{mso-style-name:列表1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.1a, li.1a, div.1a
	{mso-style-name:表1;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.37, li.37, div.37
	{mso-style-name:图说明3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.62, li.62, div.62
	{mso-style-name:表中字体6号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
p.a5, li.a5, div.a5
	{mso-style-name:正文代码;
	mso-style-link:"正文代码 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char1
	{mso-style-name:"正文代码 Char";
	mso-style-link:正文代码;
	font-family:宋体;}
p.43, li.43, div.43
	{mso-style-name:"样式 标题 4 +";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:"Arial","sans-serif";
	font-weight:bold;}
p.140, li.140, div.140
	{mso-style-name:表14;
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
p.141, li.141, div.141
	{mso-style-name:图说明14;
	mso-style-link:"图说明14 Char";
	margin-top:0cm;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:21.25pt;
	margin-bottom:.0001pt;
	text-align:center;
	text-indent:-21.25pt;
	font-size:10.5pt;
	font-family:宋体;}
span.14Char
	{mso-style-name:"图说明14 Char";
	mso-style-link:图说明14;
	font-family:宋体;}
p.a6, li.a6, div.a6
	{mso-style-name:文件目录表;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.a7, li.a7, div.a7
	{mso-style-name:"样式 正文 +";
	mso-style-link:"样式 正文 + Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char2
	{mso-style-name:"样式 正文 + Char";
	mso-style-link:"样式 正文 +";
	font-family:"Times New Roman","serif";}
p.a8, li.a8, div.a8
	{mso-style-name:表格题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.a9, li.a9, div.a9
	{mso-style-name:列表题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.aa, li.aa, div.aa
	{mso-style-name:图题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ab, li.ab, div.ab
	{mso-style-name:程序题注;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ac, li.ac, div.ac
	{mso-style-name:框中文字;
	margin-top:0cm;
	margin-right:21.0pt;
	margin-bottom:0cm;
	margin-left:21.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.125, li.125, div.125
	{mso-style-name:"样式 标题 1 + 居中2";
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	text-align:center;
	page-break-after:avoid;
	font-size:22.0pt;
	font-family:宋体;
	font-weight:bold;}
p.ad, li.ad, div.ad
	{mso-style-name:"样式 题注 + 宋体 五号 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:黑体;}
p.1b, li.1b, div.1b
	{mso-style-name:序标题1;
	margin-top:17.0pt;
	margin-right:0cm;
	margin-bottom:16.5pt;
	margin-left:0cm;
	line-height:240%;
	page-break-after:avoid;
	font-size:16.0pt;
	font-family:宋体;
	font-weight:bold;}
p.38, li.38, div.38
	{mso-style-name:序标题3;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:12.0pt;
	font-family:方正小标宋简体;}
p.63, li.63, div.63
	{mso-style-name:表中文字6号;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:7.5pt;
	font-family:宋体;}
p.64, li.64, div.64
	{mso-style-name:图中文字6号左对齐;
	margin:0cm;
	margin-bottom:.0001pt;
	line-height:10.0pt;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
p.65, li.65, div.65
	{mso-style-name:图中文字6号;
	mso-style-link:"图中文字6号 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	line-height:10.0pt;
	layout-grid-mode:char;
	font-size:7.5pt;
	font-family:宋体;}
span.6Char
	{mso-style-name:"图中文字6号 Char";
	mso-style-link:图中文字6号;
	font-family:宋体;}
p.ae, li.ae, div.ae
	{mso-style-name:图标;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.28, li.28, div.28
	{mso-style-name:图标2;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
p.af, li.af, div.af
	{mso-style-name:习题标题;
	margin-top:6.0pt;
	margin-right:0cm;
	margin-bottom:0cm;
	margin-left:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	page-break-after:avoid;
	font-size:14.0pt;
	font-family:黑体;}
p.1c, li.1c, div.1c
	{mso-style-name:部分编号1;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:16.0pt;
	font-family:宋体;}
p.af0, li.af0, div.af0
	{mso-style-name:表标题;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.af1, li.af1, div.af1
	{mso-style-name:"样式 题注 + 居中";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:宋体;}
p.ListTitle, li.ListTitle, div.ListTitle
	{mso-style-name:ListTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.FigureTitle, li.FigureTitle, div.FigureTitle
	{mso-style-name:FigureTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.TableTitle, li.TableTitle, div.TableTitle
	{mso-style-name:TableTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.ProgramTitle, li.ProgramTitle, div.ProgramTitle
	{mso-style-name:ProgramTitle;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:center;
	font-size:10.5pt;
	font-family:"Arial","sans-serif";}
p.RightText, li.RightText, div.RightText
	{mso-style-name:RightText;
	margin-top:0cm;
	margin-right:21.0pt;
	margin-bottom:0cm;
	margin-left:42.0pt;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	border:none;
	padding:0cm;
	font-size:9.0pt;
	font-family:宋体;}
p.af2, li.af2, div.af2
	{mso-style-name:表中文字小五;
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:9.0pt;
	font-family:宋体;}
p.af3, li.af3, div.af3
	{mso-style-name:关键词;
	mso-style-link:"关键词 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char3
	{mso-style-name:"关键词 Char";
	mso-style-link:关键词;
	font-family:宋体;}
p.af4, li.af4, div.af4
	{mso-style-name:文件名;
	mso-style-link:"文件名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char4
	{mso-style-name:"文件名 Char";
	mso-style-link:文件名;
	font-family:宋体;}
p.af5, li.af5, div.af5
	{mso-style-name:选项;
	mso-style-link:"选项 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char5
	{mso-style-name:"选项 Char";
	mso-style-link:选项;
	font-family:宋体;}
p.af6, li.af6, div.af6
	{mso-style-name:命令行;
	mso-style-link:"命令行 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char6
	{mso-style-name:"命令行 Char";
	mso-style-link:命令行;
	font-family:宋体;}
p.af7, li.af7, div.af7
	{mso-style-name:函数名;
	mso-style-link:"函数名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char7
	{mso-style-name:"函数名 Char";
	mso-style-link:函数名;
	font-family:宋体;}
p.af8, li.af8, div.af8
	{mso-style-name:寄存器名;
	mso-style-link:"寄存器名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char8
	{mso-style-name:"寄存器名 Char";
	mso-style-link:寄存器名;
	font-family:"Times New Roman","serif";}
p.af9, li.af9, div.af9
	{mso-style-name:变量名;
	mso-style-link:"变量名 Char";
	margin:0cm;
	margin-bottom:.0001pt;
	text-align:justify;
	text-justify:inter-ideograph;
	font-size:10.5pt;
	font-family:宋体;}
span.Char9
	{mso-style-name:"变量名 Char";
	mso-style-link:变量名;
	font-family:宋体;}
p.58, li.58, div.58
	{mso-style-name:图中文字小5号左;
	margin:0cm;
	margin-bottom:.0001pt;
	font-size:9.0pt;
	font-family:宋体;}
p.59, li.59, div.59
	{mso-style-name:图中文字小5号靠左;
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:9.0pt;
	font-family:宋体;}
p.926, li.926, div.926
	{mso-style-name:"样式 代码程序 + 左侧\:  9\.26 厘米";
	margin:0cm;
	margin-bottom:.0001pt;
	layout-grid-mode:char;
	font-size:10.0pt;
	font-family:宋体;}
span.5Char4
	{mso-style-name:"标题 5 Char";
	mso-style-link:"标题 5";
	font-weight:bold;}
span.6Char0
	{mso-style-name:"标题 6 Char";
	mso-style-link:"标题 6";
	font-family:"Arial","sans-serif";
	font-weight:bold;}
span.7Char
	{mso-style-name:"标题 7 Char";
	mso-style-link:"标题 7";
	font-weight:bold;}
span.8Char
	{mso-style-name:"标题 8 Char";
	mso-style-link:"标题 8";
	font-family:"Arial","sans-serif";}
span.9Char
	{mso-style-name:"标题 9 Char";
	mso-style-link:"标题 9";
	font-family:"Arial","sans-serif";}
span.Chara
	{mso-style-name:"脚注文本 Char";
	mso-style-link:脚注文本;
	font-family:宋体;}
span.Charb
	{mso-style-name:"批注文字 Char";
	mso-style-link:批注文字;
	font-family:宋体;}
span.Charc
	{mso-style-name:"页眉 Char";
	mso-style-link:页眉;
	font-family:宋体;}
span.Chard
	{mso-style-name:"页脚 Char";
	mso-style-link:页脚;
	font-family:宋体;}
span.Chare
	{mso-style-name:"日期 Char";
	mso-style-link:日期;
	font-family:宋体;}
span.HTMLChar
	{mso-style-name:"HTML 预设格式 Char\,HTML 预先格式化 Char\,HTML 预先格式化1 Char\,HTML 预先格式化2 Char\,HTML 预先格式化3 Char";
	mso-style-link:"HTML 预设格式\,HTML 预先格式化\,HTML 预先格式化1\,HTML 预先格式化2\,HTML 预先格式化3";
	font-family:宋体;}
span.Charf
	{mso-style-name:"批注主题 Char";
	mso-style-link:批注主题;
	font-family:宋体;
	font-weight:bold;}
span.Charf0
	{mso-style-name:"批注框文本 Char";
	mso-style-link:批注框文本;
	font-family:宋体;}
span.3CharChar1
	{mso-style-name:"图中文字3 Char Char1";
	font-family:宋体;}
span.3CharChar3
	{mso-style-name:"图中文字3 Char Char3";
	font-family:宋体;}
span.3CharChar13
	{mso-style-name:"图中文字3 Char Char13";
	font-family:宋体;}
span.3CharChar12
	{mso-style-name:"图中文字3 Char Char12";
	font-family:宋体;}
span.3CharChar11
	{mso-style-name:"图中文字3 Char Char11";
	font-family:宋体;}
.MsoChpDefault
	{font-size:10.0pt;}
 /* Page Definitions */
 @page WordSection1
	{size:595.3pt 841.9pt;
	margin:72.0pt 54.0pt 72.0pt 54.0pt;
	layout-grid:15.6pt;}
div.WordSection1
	{page:WordSection1;}
 /* List Definitions */
 ol
	{margin-bottom:0cm;}
ul
	{margin-bottom:0cm;}
-->
</style>

</head>

<body lang=ZH-CN link=blue vlink=purple style='text-justify-trim:punctuation'>

<div class=WordSection1 style='layout-grid:15.6pt'>

<p class=ab><a name="_Toc53320621"><span style='font-family:黑体'>程序</span><span
lang=EN-US>9-5 linux/kernel/blk_drv/floppy.c</span></a></p>

<div class=a align=center style='text-align:center'><span lang=EN-US>

<hr size=4 width="100%" align=center>

</span></div>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>1</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>2</span></u> <b><i>&nbsp;*&nbsp;
linux/kernel/floppy.c</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>3</span></u> <b><i>&nbsp;*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>4</span></u> <b><i>&nbsp;*&nbsp;
(C) 1991&nbsp; Linus Torvalds</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>5</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>6</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>7</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>8</span></u> <b><i>&nbsp;*
02.12.91 - Changed to static variables to indicate need for reset</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp; <u><span style='color:blue'>9</span></u> <b><i>&nbsp;*
and recalibrate. This makes some things easier (output_byte reset</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>10</span></u> <b><i>&nbsp;*
checking etc), and means less interrupt jumping in case of errors,</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>11</span></u> <b><i>&nbsp;*
so the code is hopefully easier to understand.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>12</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * 02.12.91 - </span>修改成静态变量，以适应复位和重新校正操作。这使得某些事情</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>做起来较为方便（<span
lang=EN-US>output_byte </span>复位检查等），并且意味着在出错时中断跳转</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>要少一些，所以也希望代码能更容易被理解。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>13</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>14</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>15</span></u> <b><i>&nbsp;*
This file is certainly a mess. I've tried my best to get it working,</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>16</span></u> <b><i>&nbsp;*
but I don't like programming floppies, and I have only one anyway.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>17</span></u> <b><i>&nbsp;*
Urgel. I should check for more errors, and do more graceful error</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>18</span></u> <b><i>&nbsp;*
recovery. Seems there are problems with several drives. I've tried to</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>19</span></u> <b><i>&nbsp;*
correct them. No promises. </i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>20</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>这个文件当然比较混乱。我已经尽我所能使其能够工作，但我不喜欢软驱编程，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>而且我也只有一个软驱。另外，我应该做更多的查错工作，以及改正更多的错误。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>对于某些软盘驱动器，本程序好象还存在一些问题。我已经尝试着进行纠正了，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>但不能保证问题已消失。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>21</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>22</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>23</span></u> <b><i>&nbsp;*
As with hd.c, all routines within this file can (and will) be called</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>24</span></u> <b><i>&nbsp;*
by interrupts, so extreme caution is needed. A hardware interrupt</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>25</span></u> <b><i>&nbsp;*
handler may not sleep, or a kernel panic will happen. Thus I cannot</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>26</span></u> <b><i>&nbsp;*
call &quot;floppy-on&quot; directly, but have to set a special timer interrupt</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>27</span></u> <b><i>&nbsp;*
etc.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>28</span></u> <b><i>&nbsp;*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>29</span></u> <b><i>&nbsp;*
Also, I'm not certain this works on more than 1 floppy. Bugs may</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>30</span></u> <b><i>&nbsp;*
abund.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>31</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>如同<span
lang=EN-US>hd.c</span>文件一样，该文件中的所有子程序都能够被中断调用，所以需要特别</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>地小心。硬件中断处理程序是不能睡眠的，否则内核就会傻掉<span
lang=EN-US>(</span>死机<span lang=EN-US>)</span><span lang=EN-US
style='font-family:Wingdings'>J</span>。因此不能</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>直接调用<span
lang=EN-US>&quot;floppy-on&quot;</span>，而只能设置一个特殊的定时中断等。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; *</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>另外，我不能保证该程序能在多于<span
lang=EN-US>1</span>个软驱的系统上工作，有可能存在错误。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>32</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>33</span></u>
#include &lt;linux/sched.h&gt;&nbsp; // </span>调度程序头文件，定义了任务结构<span lang=EN-US>task_struct</span>、任务<span
lang=EN-US>0</span>数据等。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>34</span></u>
#include &lt;linux/fs.h&gt;&nbsp;&nbsp;&nbsp;&nbsp; // </span>文件系统头文件。含文件表结构（<span
lang=EN-US>file</span>、<span lang=EN-US>m_inode</span>）等。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>35</span></u>
#include &lt;linux/kernel.h&gt; // </span>内核头文件。含有一些内核常用函数的原形定义。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>36</span></u>
#include &lt;linux/fdreg.h&gt;&nbsp; // </span>软驱头文件。含有软盘控制器参数的一些定义。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>37</span></u>
#include &lt;asm/system.h&gt;&nbsp;&nbsp; // </span>系统头文件。定义了设置或修改描述符<span
lang=EN-US>/</span>中断门等的嵌入汇编宏。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>38</span></u>
#include &lt;asm/io.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // io</span>头文件。定义硬件端口输入<span
lang=EN-US>/</span>输出宏汇编语句。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>39</span></u>
#include &lt;asm/segment.h&gt;&nbsp; // </span>段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>40</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>定义软驱主设备号符号常数。在驱动程序中，主设备号必须在包含<span
lang=EN-US>blk.h</span>文件之前被定义。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>因为<span lang=EN-US>blk.h</span>文件中要用到这个符号常数值来确定一些列其他相关符号常数和宏。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>41</span></u>
#define <u><span style='color:blue'>MAJOR_NR</span></u> 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>软驱的主设备号是<span lang=EN-US>2</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>42</span></u>
#include &quot;<u><span style='color:blue'>blk.h</span></u>&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>块设备头文件。定义请求结构、块设备结构和宏函数等信息。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>43</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>44</span></u>
static int <u><span style='color:blue'>recalibrate</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>标志：<span lang=EN-US>1</span>表示需要重新校正磁头位置（磁头归零道）。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>45</span></u>
static int <u><span style='color:blue'>reset</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>标志：<span lang=EN-US>1</span>表示需要进行复位操作。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>46</span></u>
static int <u><span style='color:blue'>seek</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>标志：<span lang=EN-US>1</span>表示需要执行寻道操作。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>47</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>当前数字输出寄存器<span
lang=EN-US>DOR</span>（<span lang=EN-US>Digital Output Register</span>），定义在<span
lang=EN-US>kernel/sched.c</span>，<span lang=EN-US>223</span>行。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该变量含有软驱操作中的重要标志，包括选择软驱、控制电机启动、启动复位软盘控制器以</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>及允许<span lang=EN-US>/</span>禁止<span
lang=EN-US>DMA</span>和中断请求。请参见程序列表后对<span lang=EN-US>DOR</span>寄存器的说明。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>48</span></u>
extern unsigned char <u><span style='color:blue'>current_DOR</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>49</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>字节直接数输出（嵌入汇编宏）。把值<span
lang=EN-US>val</span>输出到<span lang=EN-US>port</span>端口。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>50</span></u>
#define <u><span style='color:blue'>immoutb_p</span></u>(val,port) \</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>51</span></u>
__asm__(<i>&quot;outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:&quot;</i>::<i>&quot;a&quot;</i> ((char) (val)),<i>&quot;i&quot;</i> (port))</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>52</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这两个宏定义用于计算软驱的设备号。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参数<span lang=EN-US>x</span>是次设备号。次设备号<span
lang=EN-US> = TYPE*4 + DRIVE</span>。计算方法参见列表后。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>53</span></u>
#define <u><span style='color:blue'>TYPE</span></u>(<u><span style='color:blue'>x</span></u>)
((<u><span style='color:blue'>x</span></u>)&gt;&gt;2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;// </span>软驱类型（<span lang=EN-US>2--1.2Mb</span>，<span lang=EN-US>7--1.44Mb</span>）。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>54</span></u>
#define <u><span style='color:blue'>DRIVE</span></u>(<u><span style='color:
blue'>x</span></u>) ((<u><span style='color:blue'>x</span></u>)&amp;0x03)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>软驱序号（<span lang=EN-US>0--3</span>对应<span lang=EN-US>A--D</span>）。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>55</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>56</span></u> <b><i>&nbsp;*
Note that MAX_ERRORS=8 doesn't imply that we retry every bad read</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>57</span></u> <b><i>&nbsp;*
max 8 times - some types of errors increase the errorcount by 2,</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>58</span></u> <b><i>&nbsp;*
so we might actually retry only 5-6 times before giving up.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>59</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>注意，下面定义<span
lang=EN-US>MAX_ERRORS=8</span>并不表示对每次读错误尝试最多<span lang=EN-US>8</span>次<span
lang=EN-US> - </span>有些类型</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>的错误会把出错计数值乘<span
lang=EN-US>2</span>，所以我们实际上在放弃操作之前只需尝试<span lang=EN-US>5-6</span>遍即可。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>60</span></u>
#define <u><span style='color:blue'>MAX_ERRORS</span></u> 8</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>61</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>62</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>63</span></u> <b><i>&nbsp;*
globals used by 'result()'</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>64</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span>下面是函数<span lang=EN-US>'result()'</span>使用的全局变量<span
lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这些状态字节中各比特位的含义请参见<span
lang=EN-US>include/linux/fdreg.h</span>头文件。另参见列表后说明。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>65</span></u>
#define <u><span style='color:blue'>MAX_REPLIES</span></u> 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// FDC</span>最多返回<span lang=EN-US>7</span>字节的结果信息。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>66</span></u>
static unsigned char <u><span style='color:blue'>reply_buffer</span></u>[<u><span
style='color:blue'>MAX_REPLIES</span></u>];&nbsp; // </span>存放<span lang=EN-US>FDC</span>返回的应答结果信息。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>67</span></u>
#define <u><span style='color:blue'>ST0</span></u> (<u><span style='color:blue'>reply_buffer</span></u>[0])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>结果状态字节<span lang=EN-US>0</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>68</span></u>
#define <u><span style='color:blue'>ST1</span></u> (<u><span style='color:blue'>reply_buffer</span></u>[1])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>结果状态字节<span lang=EN-US>1</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>69</span></u>
#define <u><span style='color:blue'>ST2</span></u> (<u><span style='color:blue'>reply_buffer</span></u>[2])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>结果状态字节<span lang=EN-US>2</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>70</span></u>
#define <u><span style='color:blue'>ST3</span></u> (<u><span style='color:blue'>reply_buffer</span></u>[3])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>结果状态字节<span lang=EN-US>3</span>。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>71</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>72</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>73</span></u> <b><i>&nbsp;*
This struct defines the different floppy types. Unlike minix</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>74</span></u> <b><i>&nbsp;*
linux doesn't have a &quot;search for right type&quot;-type, as the code</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>75</span></u> <b><i>&nbsp;*
for that is convoluted and weird. I've got enough problems with</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>76</span></u> <b><i>&nbsp;*
this driver as it is.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>77</span></u> <b><i>&nbsp;*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>78</span></u> <b><i>&nbsp;*
The 'stretch' tells if the tracks need to be boubled for some</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>79</span></u> <b><i>&nbsp;*
types (ie 360kB diskette in 1.2MB drive etc). Others should</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>80</span></u> <b><i>&nbsp;*
be self-explanatory.</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>81</span></u> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>下面的软盘结构定义了不同的软盘类型。与<span
lang=EN-US>minix</span>不同的是，<span lang=EN-US>Linux</span>没有</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * &quot;</span>搜索正确的类型<span
lang=EN-US>&quot;-</span>类型，因为对其处理的代码令人费解且怪怪的。本程序</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>已经让我遇到太多的问题了。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; *</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>对某些类型的软盘（例如在<span
lang=EN-US>1.2MB</span>驱动器中的<span lang=EN-US>360kB</span>软盘等），<span lang=EN-US>'stretch'</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>用于检测磁道是否需要特殊处理。其他参数应该是自明的。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>定义软盘结构。软盘参数有：</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //
size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>大小<span
lang=EN-US>(</span>扇区数<span lang=EN-US>)</span>；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //
sect&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>每磁道扇区数；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // head&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>磁头数；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // track&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>磁道数；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // stretch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>对磁道是否要特殊处理（标志）；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // gap&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>扇区间隙长度<span lang=EN-US>(</span>字节数<span lang=EN-US>)</span>；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //
rate&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>数据传输速率；</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // spec1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>参数（高<span lang=EN-US>4</span>位步进速率，低四位磁头卸载时间）。</p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>82</span></u>
static struct <u><span style='color:blue'>floppy_struct</span></u> {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>83</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
unsigned int size, sect, <u><span style='color:blue'>head</span></u>, <u><span
style='color:blue'>track</span></u>, stretch;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>84</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
unsigned char gap,rate,spec1;</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>85</span></u> } <u><span
style='color:blue'>floppy_type</span></u>[] = {</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>86</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{&nbsp;&nbsp;&nbsp; 0, 0,0, 0,0,0x00,0x00,0x00 },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><i>/* no testing */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>87</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{&nbsp; 720, 9,2,40,0,0x2A,0x02,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* 360kB PC diskettes */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>88</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{ 2400,15,2,80,0,0x1B,0x00,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* 1.2
MB AT-diskettes */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>89</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{&nbsp; 720, 9,2,40,1,0x2A,0x02,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* 360kB in 720kB drive */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>90</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{ 1440, 9,2,80,0,0x2A,0x02,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* 3.5&quot; 720kB diskette */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>91</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{&nbsp; 720, 9,2,40,1,0x23,0x01,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/*
360kB in 1.2MB drive */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>92</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{ 1440, 9,2,80,0,0x23,0x01,0xDF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/* 720kB
in 1.2MB drive */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>93</span></u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
{ 2880,18,2,80,0,0x1B,0x00,0xCF },&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/*
1.44MB diskette */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>94</span></u> };</span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>95</span></u> </span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>96</span></u> <b><i>/*</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>97</span></u> <b><i>&nbsp;*
Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>98</span></u> <b><i>&nbsp;*
Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;<u><span style='color:blue'>99</span></u> <b><i>&nbsp;*
H is head unload time (1=16ms, 2=32ms, etc)</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>100</span></u><span
lang=EN-US> <b><i>&nbsp;*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>101</span></u><span
lang=EN-US> <b><i>&nbsp;* Spec2 is (HLD&lt;&lt;1 | ND), where HLD is head load
time (1=2ms, 2=4 ms etc)</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>102</span></u><span
lang=EN-US> <b><i>&nbsp;* and ND is set means no DMA. Hardcoded to 6 (HLD=6ms,
use DMA).</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>103</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>上面速率<span
lang=EN-US>rate</span>：<span lang=EN-US>0</span>表示<span lang=EN-US>500kbps</span>，<span
lang=EN-US>1</span>表示<span lang=EN-US>300kbps</span>，<span lang=EN-US>2</span>表示<span
lang=EN-US>250kbps</span>。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>参数<span
lang=EN-US>spec1</span>是<span lang=EN-US>0xSH</span>，其中<span lang=EN-US>S</span>是步进速率（<span
lang=EN-US>F-1ms</span>，<span lang=EN-US>E-2ms</span>，<span lang=EN-US>D=3ms</span>等），</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * H</span>是磁头卸载时间（<span
lang=EN-US>1=16ms</span>，<span lang=EN-US>2=32ms</span>等）</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; *</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * spec2</span>是（<span
lang=EN-US>HLD&lt;&lt;1 | ND</span>），其中<span lang=EN-US>HLD</span>是磁头加载时间（<span
lang=EN-US>1=2ms</span>，<span lang=EN-US>2=4ms</span>等）</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * ND</span>置位表示不使用<span
lang=EN-US>DMA</span>（<span lang=EN-US>No DMA</span>），在程序中硬编码成<span lang=EN-US>6</span>（<span
lang=EN-US>HLD=6ms</span>，使用<span lang=EN-US>DMA</span>）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>注意，上述磁头加载时间的缩写<span
lang=EN-US>HLD</span>最好写成标准的<span lang=EN-US>HLT</span>（<span lang=EN-US>Head
Load Time</span>）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>104</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // floppy_interrupt()</span>是<span
lang=EN-US>sys_call.s</span>程序中软驱中断处理过程标号。这里将在软盘初始化</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>函数<span lang=EN-US>floppy_init()</span>（第<span
lang=EN-US>469</span>行）使用它初始化中断陷阱门描述符。</p>

<p class=a><u><span lang=EN-US style='color:blue'>105</span></u><span
lang=EN-US> extern void <u><span style='color:blue'>floppy_interrupt</span></u>(void);</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这是<span lang=EN-US>boot/head.s</span>第<span
lang=EN-US>132</span>行处定义的临时软盘缓冲区。如果请求项的缓冲区处于内存<span lang=EN-US>1MB</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>以上某个地方，则需要将<span
lang=EN-US>DMA</span>缓冲区设在临时缓冲区域处。因为<span
 lang=EN-US>8237A</span>芯片只能在<span lang=EN-US>1MB</span>地</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>址范围内寻址。</p>

<p class=a><u><span lang=EN-US style='color:blue'>106</span></u><span
lang=EN-US> extern char <u><span style='color:blue'>tmp_floppy_area</span></u>[1024];</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>107</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>108</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>109</span></u><span
lang=EN-US> <b><i>&nbsp;* These are global variables, as that's the easiest way
to give</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>110</span></u><span
lang=EN-US> <b><i>&nbsp;* information to interrupts. They are the data used for
the current</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>111</span></u><span
lang=EN-US> <b><i>&nbsp;* request.</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>112</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>下面是一些全局变量，因为这是将信息传给中断程序最简单的方式。它们</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>用于当前请求项的数据。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>这些所谓的“全局变量”是指在软盘中断处理程序中调用的<span
lang=EN-US>C</span>函数使用的变量。当然这些</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // C</span>函数都在本程序内。</p>

<p class=a><u><span lang=EN-US style='color:blue'>113</span></u><span
lang=EN-US> static int <u><span style='color:blue'>cur_spec1</span></u> = -1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>当前软盘参数<span lang=EN-US>spec1</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>114</span></u><span
lang=EN-US> static int <u><span style='color:blue'>cur_rate</span></u> = -1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前软盘转速<span lang=EN-US>rate</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>115</span></u><span
lang=EN-US> static struct <u><span style='color:blue'>floppy_struct</span></u>
* <u><span style='color:blue'>floppy</span></u> = <u><span style='color:blue'>floppy_type</span></u>;&nbsp;
// </span>软盘类型结构数组指针。</p>

<p class=a><u><span lang=EN-US style='color:blue'>116</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>current_drive</span></u>
= 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前驱动器号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>117</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>sector</span></u>
= 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前扇区号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>118</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>head</span></u> =
0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前磁头号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>119</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>track</span></u> =
0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>120</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>seek_track</span></u>
= 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>寻道磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>121</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>current_track</span></u>
= 255;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>当前磁头所在磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>122</span></u><span
lang=EN-US> static unsigned char <u><span style='color:blue'>command</span></u>
= 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>读<span lang=EN-US>/</span>写命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>123</span></u><span
lang=EN-US> unsigned char <u><span style='color:blue'>selected</span></u> = 0; &nbsp;&nbsp;&nbsp;//
</span>软驱已选定标志。在处理请求项之前要首先选定软驱。</p>

<p class=a><u><span lang=EN-US style='color:blue'>124</span></u><span
lang=EN-US> struct <u><span style='color:blue'>task_struct</span></u> * <u><span
style='color:blue'>wait_on_floppy_select</span></u> = <u><span
style='color:blue'>NULL</span></u>;&nbsp;&nbsp; // </span>等待选定软驱的任务队列。</p>

<p class=a><u><span lang=EN-US style='color:blue'>125</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>取消选定软驱。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果函数参数指定的软驱<span
lang=EN-US>nr</span>当前并没有被选定，则显示警告信息。然后复位软驱已选定标志</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // selected</span>，并唤醒等待选择该软驱的任务。数字输出寄存器<span
lang=EN-US>(DOR)</span>的低<span lang=EN-US>2</span>位用于指定选择的软</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>驱（<span lang=EN-US>0-3</span>对应<span
lang=EN-US>A-D</span>）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>126</span></u><span
lang=EN-US> void <u><span style='color:blue'>floppy_deselect</span></u>(unsigned
int nr)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>127</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>128</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nr != (<u><span
style='color:blue'>current_DOR</span></u> &amp; 3))</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>129</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>printk</span></u>(<i>&quot;floppy_deselect: drive
not selected\n\r&quot;</i>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>130</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>selected</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>复位软驱已选定标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>131</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>wake_up</span></u>(&amp;<u><span style='color:blue'>wait_on_floppy_select</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>唤醒等待的任务。</p>

<p class=a><u><span lang=EN-US style='color:blue'>132</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>133</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>134</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>135</span></u><span
lang=EN-US> <b><i>&nbsp;* floppy-change is never called from an interrupt, so
we can relax a bit</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>136</span></u><span
lang=EN-US> <b><i>&nbsp;* here, sleep etc. Note that floppy-on tries to set
current_DOR to point</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>137</span></u><span
lang=EN-US> <b><i>&nbsp;* to the desired drive, but it will probably not
survive the sleep if</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>138</span></u><span
lang=EN-US> <b><i>&nbsp;* several floppies are used at the same time: thus the
loop.</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>139</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * floppy-change()</span>不是从中断程序中调用的，所以这里我们可以轻松一下，睡眠等。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>注意<span
lang=EN-US>floppy-on()</span>会尝试设置<span lang=EN-US>current_DOR</span>指向所需的驱动器，但当同时使用几个</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>软盘时不能睡眠：因此此时只能使用循环方式。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>检测指定软驱中软盘更换情况。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参数<span lang=EN-US>nr</span>是软驱号。如果软盘更换了则返回<span
lang=EN-US>1</span>，否则返回<span lang=EN-US>0</span>。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数首先选定参数指定的软驱<span
lang=EN-US>nr</span>，然后测试软盘控制器的数字输入寄存器<span lang=EN-US>DIR</span>的值，以判</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>断驱动器中的软盘是否被更换过。该函数由程序<span
lang=EN-US>fs/buffer.c</span>中的 <span lang=EN-US>check_disk_change()</span>函</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>数调用（第<span lang=EN-US>119</span>行）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>140</span></u><span
lang=EN-US> int <u><span style='color:blue'>floppy_change</span></u>(unsigned
int nr)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>141</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先要让软驱中软盘旋转起来并达到正常工作转速。这需要花费一定时间。采用的方法是利</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>用<span lang=EN-US>kernel/sched.c</span>中软盘定时函数<span
lang=EN-US>do_floppy_timer()</span>进行一定的延时处理。<span lang=EN-US>floppy_on()</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>函数则用于判断延时是否到（<span
lang=EN-US>mon_timer[nr]==0?</span>），若没有到则让当前进程继续睡眠等待。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若延时到则<span lang=EN-US>do_floppy_timer()</span>会唤醒当前进程。</p>

<p class=a><u><span lang=EN-US style='color:blue'>142</span></u><span
lang=EN-US> repeat:</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>143</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>floppy_on</span></u>(nr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>启动并等待指定软驱<span lang=EN-US>nr</span>（<span lang=EN-US>kernel/sched.c</span>，第<span
lang=EN-US>251</span>行）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在软盘启动（旋转）之后，我们来查看一下当前选择的软驱是不是函数参数指定的软驱<span
lang=EN-US>nr</span>。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果当前选择的软驱不是指定的软驱<span
lang=EN-US>nr</span>，并且已经选定了其他软驱，则让当前任务进入可</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>中断等待状态，以等待其他软驱被取消选定。参见上面<span
lang=EN-US>floppy_deselect()</span>。 如果当前没</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>有选择其他软驱或者其他软驱被取消选定而使当前任务被唤醒时，
当前软驱仍然不是指定</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>的软驱<span lang=EN-US>nr</span>，则跳转到函数开始处重新循环等待。</p>

<p class=a><u><span lang=EN-US style='color:blue'>144</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((<u><span
style='color:blue'>current_DOR</span></u> &amp; 3) != nr &amp;&amp; <u><span
style='color:blue'>selected</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>145</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>sleep_on</span></u>(&amp;<u><span style='color:
blue'>wait_on_floppy_select</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>146</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((<u><span
style='color:blue'>current_DOR</span></u> &amp; 3) != nr)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>147</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
goto repeat;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>现在软盘控制器已选定我们指定的软驱<span
lang=EN-US>nr</span>。于是取数字输入寄存器<span lang=EN-US>DIR</span>的值，如果其最高</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>位（位<span lang=EN-US>7</span>）置位，则表示软盘已更换，此时即可关闭马达并返回<span
lang=EN-US>1</span>退出。 否则关闭马达返</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>回<span lang=EN-US>0</span>退出。表示磁盘没有被更换。</p>

<p class=a><u><span lang=EN-US style='color:blue'>148</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>inb</span></u>(<u><span style='color:blue'>FD_DIR</span></u>)
&amp; 0x80) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>149</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>floppy_off</span></u>(nr);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>150</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>151</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>152</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>floppy_off</span></u>(nr);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>153</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>154</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>155</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>复制内存缓冲块，共<span
lang=EN-US>1024</span>字节。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>从内存地址<span lang=EN-US>from</span>处复制<span
lang=EN-US>1024</span>字节数据到地址<span lang=EN-US>to</span>处。</p>

<p class=a><u><span lang=EN-US style='color:blue'>156</span></u><span
lang=EN-US> #define <u><span style='color:blue'>copy_buffer</span></u>(from,to)
\</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>157</span></u><span
lang=EN-US> __asm__(<i>&quot;cld ; rep ; movsl&quot;</i> \</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>158</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ::<i>&quot;c&quot;</i>
(<u><span style='color:blue'>BLOCK_SIZE</span></u>/4),<i>&quot;S&quot;</i>
((long)(from)),<i>&quot;D&quot;</i> ((long)(to)) \</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>159</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<i>&quot;cx&quot;</i>,<i>&quot;di&quot;</i>,<i>&quot;si&quot;</i>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>160</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>设置（初始化）软盘<span
lang=EN-US>DMA</span>通道。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>软盘中数据读写操作是使用<span
lang=EN-US>DMA</span>进行的。因此在每次进行数据传输之前需要设置<span lang=EN-US>DMA</span>芯片</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>上专门用于软驱的通道<span
lang=EN-US>2</span>。有关<span lang=EN-US>DMA</span>编程方法请参见程序列表后的信息。</p>

<p class=a><u><span lang=EN-US style='color:blue'>161</span></u><span
lang=EN-US> static void <u><span style='color:blue'>setup_DMA</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>162</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>163</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long addr = (long) <u><span
style='color:blue'>CURRENT</span></u>-&gt;buffer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前请求项缓冲区所处内存地址。</p>

<p class=a><u><span lang=EN-US style='color:blue'>164</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先检测请求项的缓冲区所在位置。如果缓冲区处于内存<span
lang=EN-US>1MB</span>以上的某个地方，则需要将</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp; &nbsp;// DMA</span>缓冲区设在临时缓冲区域（<span
lang=EN-US>tmp_floppy_area</span>）处。因为<span
 lang=EN-US>8237A</span>芯片只能在<span lang=EN-US>1MB</span>地址范</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>围内寻址。如果是写盘命令，则还需要把数据从请求项缓冲区复制到该临时区域。</p>

<p class=a><u><span lang=EN-US style='color:blue'>165</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>cli</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>166</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (addr &gt;=
0x100000) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>167</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
addr = (long) <u><span style='color:blue'>tmp_floppy_area</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>168</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>command</span></u> == <u><span
style='color:blue'>FD_WRITE</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>169</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>copy_buffer</span></u>(<u><span style='color:blue'>CURRENT</span></u>-&gt;buffer,<u><span
style='color:blue'>tmp_floppy_area</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>170</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>接下来我们开始设置<span
lang=EN-US>DMA</span>通道<span lang=EN-US>2</span>。在开始设置之前需要先屏蔽该通道。单通道屏蔽寄存器</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>端口为<span lang=EN-US>0x0A</span>。位<span
lang=EN-US>0-1</span>指定<span lang=EN-US>DMA</span>通道<span lang=EN-US>(0--3)</span>，位<span
lang=EN-US>2</span>：<span lang=EN-US>1</span>表示屏蔽，<span lang=EN-US>0</span>表示允许请求。
然后向</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // DMA</span>控制器端口<span
lang=EN-US>12</span>和<span lang=EN-US>11</span>写入方式字（读盘是<span lang=EN-US>0x46</span>，写盘则是<span
lang=EN-US>0x4A</span>）。 再写入传输使用</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>缓冲区地址<span lang=EN-US>addr</span>和需要传输的字节数<span
lang=EN-US>0x3ff</span>（<span lang=EN-US>0--1023</span>）。最后复位对<span lang=EN-US>DMA</span>通道<span
lang=EN-US>2</span>的屏蔽，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>开放<span lang=EN-US>DMA2</span>请求<span
lang=EN-US>DREQ</span>信号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>171</span></u><span
lang=EN-US> <b><i>/* mask DMA 2 */</i></b>&nbsp;&nbsp;&nbsp; /* </span>屏蔽<span
lang=EN-US>DMA</span>通道<span lang=EN-US>2 */</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>172</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(4|2,10);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>173</span></u><span
lang=EN-US> <b><i>/* output command byte. I don't know why, but everyone
(minix, */</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>174</span></u><span
lang=EN-US> <b><i>/* sanches &amp; canton) output this twice, first to 12 then
to 11 */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span>输出命令字节。我是不知道为什么，但是每个人（<span
lang=EN-US>minix</span>，<span lang=EN-US>*/</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* sanches</span>和<span
lang=EN-US>canton</span>）都输出两次，首先是<span lang=EN-US>12</span>口，然后是<span
lang=EN-US>11</span>口<span lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面嵌入汇编代码向<span
lang=EN-US>DMA</span>控制器的“清除先后触发器”端口<span lang=EN-US>12</span>和方式寄存器端口<span
lang=EN-US>11</span>写入</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>方式字（读盘时是<span
lang=EN-US>0x46</span>，写盘是<span lang=EN-US>0x4A</span>）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>由于各通道的地址和计数寄存器都是<span
lang=EN-US>16</span>位的，因此在设置他们时都需要分<span lang=EN-US>2</span>次进行操作。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>一次访问低字节，另一次访问高字节。而实际在写哪个字节则由先后触发器的状态决定。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>当触发器为<span lang=EN-US>0</span>时，则访问低字节；当字节触发器为<span
lang=EN-US>1</span>时，则访问高字节。每访问一次，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该触发器的状态就变化一次。而写端口<span
lang=EN-US>12</span>就可以将触发器置成<span lang=EN-US>0</span>状态，从而对<span lang=EN-US>16</span>位寄存</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>器的设置从低字节开始。</p>

<p class=a><u><span lang=EN-US style='color:blue'>175</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __asm__(<i>&quot;outb
%%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t&quot;</i></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>176</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>&quot;outb
%%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:&quot;</i>::</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>177</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>&quot;a&quot;</i>
((char) ((<u><span style='color:blue'>command</span></u> == <u><span
style='color:blue'>FD_READ</span></u>)?<u><span style='color:blue'>DMA_READ</span></u>:<u><span
style='color:blue'>DMA_WRITE</span></u>)));</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>178</span></u><span
lang=EN-US> <b><i>/* 8 low bits of addr */</i></b>&nbsp;&nbsp;&nbsp;&nbsp; /* </span>地址低<span
lang=EN-US>0-7</span>位<span lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>向<span lang=EN-US>DMA</span>通道<span
lang=EN-US>2</span>写入基<span lang=EN-US>/</span>当前地址寄存器（端口<span lang=EN-US>4</span>）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>179</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(addr,4);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>180</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addr &gt;&gt;= 8;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>181</span></u><span
lang=EN-US> <b><i>/* bits 8-15 of addr */</i></b>&nbsp;&nbsp;&nbsp; /* </span>地址高<span
lang=EN-US>8-15</span>位<span lang=EN-US> */</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>182</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(addr,4);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>183</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addr &gt;&gt;= 8;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>184</span></u><span
lang=EN-US> <b><i>/* bits 16-19 of addr */</i></b>&nbsp;&nbsp;&nbsp; /* </span>地址<span
lang=EN-US>16-19</span>位<span lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // DMA</span>只可以在<span
lang=EN-US>1MB</span>内存空间内寻址，其高<span lang=EN-US>16-19</span>位地址需放入页面寄存器<span
lang=EN-US>(</span>端口<span lang=EN-US>0x81)</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>185</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(addr,0x81);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>186</span></u><span
lang=EN-US> <b><i>/* low 8 bits of count-1 (1024-1=0x3ff) */</i></b> &nbsp;/* </span>计数器低<span
lang=EN-US>8</span>位<span lang=EN-US>(1024-1 = 0x3ff) */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>向<span lang=EN-US>DMA</span>通道<span
lang=EN-US>2</span>写入基<span lang=EN-US>/</span>当前字节计数器值（端口<span lang=EN-US>5</span>）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>187</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(0xff,5);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>188</span></u><span
lang=EN-US> <b><i>/* high 8 bits of count-1 */</i></b>&nbsp;&nbsp;&nbsp; /* </span>计数器高<span
lang=EN-US>8</span>位<span lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>一次共传输<span lang=EN-US>1024</span>字节（两个扇区）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>189</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(3,5);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>190</span></u><span
lang=EN-US> <b><i>/* activate DMA 2 */</i></b>&nbsp;&nbsp;&nbsp; /* </span>开启<span
lang=EN-US>DMA</span>通道<span lang=EN-US>2</span>的请求<span lang=EN-US> */</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>191</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>immoutb_p</span></u>(0|2,10);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>192</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sti</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>193</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>194</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>向软驱控制器输出一个字节命令或参数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在向控制器发送一个字节之前，控制器需要处于准备好状态，并且数据传输方向必须设置</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>成从<span lang=EN-US>CPU
</span>到 <span lang=EN-US>FDC</span>，因此函数需要首先读取控制器状态信息。这里使用了循环查询方式，以</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>作适当延时。若出错，则会设置复位标志<span
lang=EN-US>reset</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>195</span></u><span
lang=EN-US> static void <u><span style='color:blue'>output_byte</span></u>(char
byte)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>196</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>197</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int counter;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>198</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char
status;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>199</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>循环读取主状态控制器<span
lang=EN-US>FD_STATUS</span>（<span lang=EN-US>0x3f4</span>）的状态。如果所读状态是 <span
lang=EN-US>STATUS_READY </span>并且</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>方向位<span lang=EN-US>STATUS_DIR
= 0</span>（<span lang=EN-US>CPU</span><span lang=EN-US style='font-family:Wingdings'>à</span><span
lang=EN-US>FDC</span>），则向数据端口输出指定字节。</p>

<p class=a><u><span lang=EN-US style='color:blue'>200</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>201</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>202</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(counter = 0 ;
counter &lt; 10000 ; counter++) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>203</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
status = <u><span style='color:blue'>inb_p</span></u>(<u><span
style='color:blue'>FD_STATUS</span></u>) &amp; (<u><span style='color:blue'>STATUS_READY</span></u>
| <u><span style='color:blue'>STATUS_DIR</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>204</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (status == <u><span style='color:blue'>STATUS_READY</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>205</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>outb</span></u>(byte,<u><span style='color:blue'>FD_DATA</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>206</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>207</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;}</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>208</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果到循环<span lang=EN-US>1</span>万次结束还不能发送，则置复位标志，并打印出错信息。</p>

<p class=a><u><span lang=EN-US style='color:blue'>209</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>reset</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>210</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>printk</span></u>(<i>&quot;Unable to send byte to
FDC\n\r&quot;</i>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>211</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>212</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>读取<span lang=EN-US>FDC</span>执行的结果信息。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>结果信息最多<span
lang=EN-US>7</span>个字节，存放在数组<span lang=EN-US>reply_buffer[]</span>中。返回读入的结果字节数，若返回</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>值<span lang=EN-US> =
-1</span>，则表示出错。程序处理方式与上面函数类似。</p>

<p class=a><u><span lang=EN-US style='color:blue'>213</span></u><span
lang=EN-US> static int <u><span style='color:blue'>result</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>214</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>215</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = 0, counter,
status;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>216</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若复位标志已置位，则立刻退出。去执行后续程序中的复位操作。否则循环读取主状态控</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>制器<span lang=EN-US>FD_STATUS</span>（<span
lang=EN-US>0x3f4</span>）的状态。如果读取的控制器状态是<span
lang=EN-US>READY</span>，表示已经没有数据可</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>取，则返回已读取的字节数<span
lang=EN-US>i</span>。如果控制器状态是方向标志置位（<span lang=EN-US>CPU</span><span lang=EN-US
style='font-family:Wingdings'>&szlig;</span><span lang=EN-US>FDC</span>）、已准备好、</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>忙，表示有数据可读取。 于是把控制器中的结果数据读入到应答结果数组中。
最多读取</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // MAX_REPLIES</span>（<span
lang=EN-US>7</span>）个字节。</p>

<p class=a><u><span lang=EN-US style='color:blue'>217</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>218</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return -1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>219</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (counter = 0 ;
counter &lt; 10000 ; counter++) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>220</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
status = <u><span style='color:blue'>inb_p</span></u>(<u><span
style='color:blue'>FD_STATUS</span></u>)&amp;(<u><span style='color:blue'>STATUS_DIR</span></u>|<u><span
style='color:blue'>STATUS_READY</span></u>|<u><span style='color:blue'>STATUS_BUSY</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>221</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (status == <u><span style='color:blue'>STATUS_READY</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>222</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>223</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (status == (<u><span style='color:blue'>STATUS_DIR</span></u>|<u><span
style='color:blue'>STATUS_READY</span></u>|<u><span style='color:blue'>STATUS_BUSY</span></u>))
{</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>224</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (i &gt;= <u><span style='color:blue'>MAX_REPLIES</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>225</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
break;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>226</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>reply_buffer</span></u>[i++] = <u><span
style='color:blue'>inb_p</span></u>(<u><span style='color:blue'>FD_DATA</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>227</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
}</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>228</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果到循环<span lang=EN-US>1</span>万次结束还不能发送，则置复位标志，并打印出错信息。</p>

<p class=a><u><span lang=EN-US style='color:blue'>229</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>reset</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>230</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>printk</span></u>(<i>&quot;Getstatus times out\n\r&quot;</i>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>231</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>232</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>233</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘读写出错处理函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数根据软盘读写出错次数来确定需要采取的进一步行动。如果当前处理的请求项出错</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>次数大于规定的最大出错次数<span
lang=EN-US>MAX_ERRORS</span>（<span lang=EN-US>8</span>次），则不再对当前请求项作进一步的操作</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>尝试。如果读<span
lang=EN-US>/</span>写出错次数已经超过<span lang=EN-US>MAX_ERRORS/2</span>，则需要对软驱作复位处理，于是设置</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>复位标志<span lang=EN-US>reset</span>。否则若出错次数还不到最大值的一半，则只需重新校正一下磁头位置，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>于是设置重新校正标志<span
lang=EN-US>recalibrate</span>。真正的复位和重新校正处理会在后续的程序中进行。</p>

<p class=a><u><span lang=EN-US style='color:blue'>234</span></u><span
lang=EN-US> static void <u><span style='color:blue'>bad_flp_intr</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>235</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先把当前请求项出错次数增<span
lang=EN-US>1</span>。如果当前请求项出错次数大于最大允许出错次数，则取</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>消选定当前软驱，并结束该请求项（缓冲区内容没有被更新）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>236</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>CURRENT</span></u>-&gt;errors++;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>237</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>CURRENT</span></u>-&gt;errors &gt; <u><span
style='color:blue'>MAX_ERRORS</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>238</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>floppy_deselect</span></u>(<u><span
style='color:blue'>current_drive</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>239</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>end_request</span></u>(0);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>240</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果当前请求项出错次数大于最大允许出错次数的一半，则置复位标志，需对软驱进行复</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>位操作，然后再试。否则软驱需重新校正一下再试。</p>

<p class=a><u><span lang=EN-US style='color:blue'>241</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>CURRENT</span></u>-&gt;errors &gt; <u><span
style='color:blue'>MAX_ERRORS</span></u>/2)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>242</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>reset</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>243</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>244</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>recalibrate</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>245</span></u><span
lang=EN-US> }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>246</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>247</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>248</span></u><span
lang=EN-US> <b><i>&nbsp;* Ok, this interrupt is called after a DMA read/write
has succeeded,</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>249</span></u><span
lang=EN-US> <b><i>&nbsp;* so we check the results, and copy any buffers.</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>250</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * OK</span>，下面的中断处理函数是在<span
lang=EN-US>DMA</span>读<span lang=EN-US>/</span>写成功后调用的，这样我们就可以检查</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>执行结果，并复制缓冲区中的数据。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘读写操作中断调用函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数在软驱控制器操作结束后引发的中断处理过程中被调用。函数首先读取操作结果状</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>态信息，据此判断操作是否出现问题并作相应处理。
如果读<span lang=EN-US>/</span>写操作成功，那么若请求项</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>是读操作并且其缓冲区在内存<span
lang=EN-US>1MB</span>以上位置，则需要把数据从软盘临时缓冲区复制到请求</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>项的缓冲区。</p>

<p class=a><u><span lang=EN-US style='color:blue'>251</span></u><span
lang=EN-US> static void <u><span style='color:blue'>rw_interrupt</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>252</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>读取<span lang=EN-US>FDC</span>执行的结果信息。如果返回结果字节数不等于<span
lang=EN-US>7</span>，或者状态字节<span lang=EN-US>0</span>、<span lang=EN-US>1</span>或<span
lang=EN-US>2</span>中存在</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>出错标志，那么若是写保护就显示出错信息，释放当前驱动器，并结束当前请求项。否则</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>就执行出错计数处理。然后继续执行软盘请求项操作。以下状态的含义参见<span
lang=EN-US>fdreg.h</span>文件。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // ( 0xf8 = ST0_INTR | ST0_SE |
ST0_ECE | ST0_NR )</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // ( 0xbf = ST1_EOC | ST1_CRC | ST1_OR
| ST1_ND | ST1_WP | ST1_MAM</span>，应该是<span lang=EN-US>0xb7)</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // ( 0x73 = ST2_CM | ST2_CRC |
ST2_WC | ST2_BC | ST2_MAM )</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>253</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>result</span></u>() != 7 || (<u><span style='color:blue'>ST0</span></u>
&amp; 0xf8) || (<u><span style='color:blue'>ST1</span></u> &amp; 0xbf) || (<u><span
style='color:blue'>ST2</span></u> &amp; 0x73)) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>254</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
if (<u><span style='color:blue'>ST1</span></u> &amp; 0x02) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// 0x02 = ST1_WP - Write Protected</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>255</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>printk</span></u>(<i>&quot;Drive %d is write
protected\n\r&quot;</i>,<u><span style='color:blue'>current_drive</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>256</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>floppy_deselect</span></u>(<u><span
style='color:blue'>current_drive</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>257</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>end_request</span></u>(0);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>258</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
} else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>259</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;<u><span style='color:blue'>bad_flp_intr</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>260</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>261</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>262</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果当前请求项的缓冲区位于<span
lang=EN-US>1MB</span>地址以上，则说明此次软盘读操作的内容还放在临时缓</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>冲区内，需要复制到当前请求项的缓冲区中（因为<span
lang=EN-US>DMA</span>只能在<span lang=EN-US>1MB</span>地址范围寻址）。最后</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>释放当前软驱（取消选定），执行当前请求项结束处理：唤醒等待该请求项的进行，唤醒</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>等待空闲请求项的进程（若有的话），从软驱设备请求项链表中删除本请求项。再继续执</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>行其他软盘请求项操作。</p>

<p class=a><u><span lang=EN-US style='color:blue'>263</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>command</span></u> == <u><span style='color:blue'>FD_READ</span></u>
&amp;&amp; (unsigned long)(<u><span style='color:blue'>CURRENT</span></u>-&gt;buffer)
&gt;= 0x100000)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>264</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>copy_buffer</span></u>(<u><span style='color:blue'>tmp_floppy_area</span></u>,<u><span
style='color:blue'>CURRENT</span></u>-&gt;buffer);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>265</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>floppy_deselect</span></u>(<u><span style='color:blue'>current_drive</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>266</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>end_request</span></u>(1);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>267</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>268</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>269</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>设置<span lang=EN-US>DMA</span>通道<span
lang=EN-US>2</span>并向软盘控制器输出命令和参数（输出<span lang=EN-US>1</span>字节命令 <span
lang=EN-US>+ 0~7</span>字节参数）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若<span lang=EN-US>reset</span>标志没有置位，那么在该函数退出并且软盘控制器执行完相应读<span
lang=EN-US>/</span>写操作后就会</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>产生一个软盘中断请求，并开始执行软盘中断处理程序。</p>

<p class=a><u><span lang=EN-US style='color:blue'>270</span></u><span
lang=EN-US> inline void <u><span style='color:blue'>setup_rw_floppy</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>271</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>272</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>setup_DMA</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>初始化软盘<span lang=EN-US>DMA</span>通道。</p>

<p class=a><u><span lang=EN-US style='color:blue'>273</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_floppy = <u><span
style='color:blue'>rw_interrupt</span></u>;&nbsp; // </span>置软盘中断调用函数指针。</p>

<p class=a><u><span lang=EN-US style='color:blue'>274</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>command</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送命令字节。</p>

<p class=a><u><span lang=EN-US style='color:blue'>275</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>head</span></u>&lt;&lt;2
| <u><span style='color:blue'>current_drive</span></u>);&nbsp; // </span>参数：磁头号<span
lang=EN-US>+</span>驱动器号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>276</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>track</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>参数：磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>277</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>head</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>参数：磁头号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>278</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>sector</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>参数：起始扇区号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>279</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<b><i>/* sector size = 512 */</i></b> // </span>参数：<span lang=EN-US>(N=2)512</span>字节。</p>

<p class=a><u><span lang=EN-US style='color:blue'>280</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>floppy</span></u>-&gt;sect);
// </span>参数：每磁道扇区数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>281</span></u><span
lang=EN-US> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>floppy</span></u>-&gt;gap);&nbsp;
// </span>参数：扇区间隔长度。</p>

<p class=a><u><span lang=EN-US style='color:blue'>282</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(0xFF);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><i>/*
sector size (0xff when n!=0 ?) */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>参数：当<span lang=EN-US>N=0</span>时，扇区定义的字节长度，这里无用。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若上述任何一个<span
lang=EN-US>output_byte()</span>操作出错，则会设置复位标志<span lang=EN-US>reset</span>。此时即会立刻去执行</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // do_fd_request()</span>中的复位处理代码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>283</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>284</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>285</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>286</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>287</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>288</span></u><span
lang=EN-US> <b><i>&nbsp;* This is the routine called after every seek (or
recalibrate) interrupt</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>289</span></u><span
lang=EN-US> <b><i>&nbsp;* from the floppy controller. Note that the
&quot;unexpected interrupt&quot; routine</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>290</span></u><span
lang=EN-US> <b><i>&nbsp;* also does a recalibrate, but doesn't come here.</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>291</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>该子程序是在每次软盘控制器寻道（或重新校正）中断中被调用的。注意</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * &quot;unexpected
interrupt&quot;(</span>意外中断<span lang=EN-US>)</span>子程序也会执行重新校正操作，但不在此地。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>寻道处理结束后中断过程中调用的<span
lang=EN-US>C</span>函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先发送检测中断状态命令，获得状态信息<span
lang=EN-US>ST0</span>和磁头所在磁道信息。若出错则执行错误</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>计数检测处理或取消本次软盘操作请求项。否则根据状态信息设置当前磁道变量，然后调</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>用函数<span lang=EN-US>setup_rw_floppy()</span>设置<span
lang=EN-US>DMA</span>并输出软盘读写命令和参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>292</span></u><span
lang=EN-US> static void <u><span style='color:blue'>seek_interrupt</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>293</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先发送检测中断状态命令，以获取寻道操作执行的结果。该命令不带参数。返回结果信</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>息是两个字节：<span
lang=EN-US>ST0</span>和磁头当前磁道号。然后读取<span lang=EN-US>FDC</span>执行的结果信息。 如果返回结果字</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>节数不等于<span lang=EN-US>2</span>，或者<span
lang=EN-US>ST0</span>不为寻道结束，或者磁头所在磁道（<span lang=EN-US>ST1</span>）不等于设定磁道，则说</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>明发生了错误。于是执行检测错误计数处理，然后继续执行软盘请求项或执行复位处理。</p>

<p class=a><u><span lang=EN-US style='color:blue'>294</span></u><span
lang=EN-US> <b><i>/* sense drive status */</i></b>&nbsp;&nbsp;&nbsp; /* </span>检测驱动器状态<span
lang=EN-US> */</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>295</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SENSEI</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>296</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>result</span></u>() != 2 || (<u><span style='color:blue'>ST0</span></u>
&amp; 0xF8) != 0x20 || <u><span style='color:blue'>ST1</span></u> != <u><span
style='color:blue'>seek_track</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>297</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>bad_flp_intr</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>298</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>299</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>300</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若寻道操作成功，则继续执行当前请求项的软盘操作，即向软盘控制器发送命令和参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>301</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>current_track</span></u> = <u><span style='color:blue'>ST1</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>设置当前磁道。</p>

<p class=a><u><span lang=EN-US style='color:blue'>302</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>setup_rw_floppy</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>设置<span lang=EN-US>DMA</span>并输出软盘操作命令和参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>303</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>304</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>305</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>306</span></u><span
lang=EN-US> <b><i>&nbsp;* This routine is called when everything should be
correctly set up</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>307</span></u><span
lang=EN-US> <b><i>&nbsp;* for the transfer (ie floppy motor is on and the
correct floppy is</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>308</span></u><span
lang=EN-US> <b><i>&nbsp;* selected).</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>309</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /*</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>该函数是在传输操作的所有信息都正确设置好后被调用的（即软驱马达已开启</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>并且已选择了正确的软盘（软驱）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>读写数据传输函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>310</span></u><span
lang=EN-US> static void <u><span style='color:blue'>transfer</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>311</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先检查当前驱动器参数是否就是指定驱动器的参数。若不是就发送设置驱动器参数命令</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>及相应参数（参数<span
lang=EN-US>1</span>：高<span lang=EN-US>4</span>位步进速率，低四位磁头卸载时间；参数<span
lang=EN-US>2</span>：磁头加载时间）。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>然后判断当前数据传输速率是否与指定驱动器的一致，若不是就发送指定软驱的速率值到</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>数据传输速率控制寄存器<span
lang=EN-US>(FD_DCR)</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>312</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>cur_spec1</span></u> != <u><span style='color:blue'>floppy</span></u>-&gt;spec1)
{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>检测当前参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>313</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>cur_spec1</span></u> = <u><span style='color:blue'>floppy</span></u>-&gt;spec1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>314</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SPECIFY</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送设置磁盘参数命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>315</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>cur_spec1</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<b><i>/* hut etc */</i></b>&nbsp; // </span>发送参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>316</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(6);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<b><i>/* Head load time =6ms, DMA */</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>317</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>318</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>cur_rate</span></u> != <u><span style='color:blue'>floppy</span></u>-&gt;rate)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>检测当前速率。</p>

<p class=a><u><span lang=EN-US style='color:blue'>319</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>outb_p</span></u>(<u><span style='color:blue'>cur_rate</span></u>
= <u><span style='color:blue'>floppy</span></u>-&gt;rate,<u><span
style='color:blue'>FD_DCR</span></u>);</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若上面任何一个<span
lang=EN-US>output_byte()</span>操作执行出错，则复位标志<span lang=EN-US>reset</span>就会被置位。因此这里</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>我们需要检测一下<span
lang=EN-US>reset</span>标志。若<span lang=EN-US>reset</span>真的被置位了，就立刻去执行<span
lang=EN-US>do_fd_request()</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>中的复位处理代码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>320</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>321</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>322</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>323</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果此时寻道标志为零（即不需要寻道），则设置<span
lang=EN-US>DMA</span>并向软盘控制器发送相应操作命令</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>和参数后返回。否则就执行寻道处理，于是首先置软盘中断处理调用函数为寻道中断函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果起始磁道号不等于零则发送磁头寻道命令和参数。所使用的参数即是第<span
lang=EN-US>112--121</span>行</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>上设置的全局变量值。如果起始磁道号<span
lang=EN-US>seek_track</span>为<span lang=EN-US>0</span>，则执行重新校正命令让磁头归零</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>324</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!<u><span
style='color:blue'>seek</span></u>) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>325</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>setup_rw_floppy</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送命令参数块。</p>

<p class=a><u><span lang=EN-US style='color:blue'>326</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>327</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>328</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_floppy = <u><span
style='color:blue'>seek_interrupt</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>寻道中断调用的<span lang=EN-US>C</span>函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>329</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>seek_track</span></u>) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>起始磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>330</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SEEK</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送磁头寻道命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>331</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>head</span></u>&lt;&lt;2
| <u><span style='color:blue'>current_drive</span></u>);// </span>发送参数：磁头号<span
lang=EN-US>+</span>当前软驱号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>332</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>seek_track</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送参数：磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>333</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>334</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_RECALIBRATE</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送重新校正命令（磁头归零）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>335</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>head</span></u>&lt;&lt;2
| <u><span style='color:blue'>current_drive</span></u>);// </span>发送参数：磁头号<span
lang=EN-US>+</span>当前软驱号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>336</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>同样地，若上面任何一个<span
lang=EN-US>output_byte()</span>操作执行出错，则复位标志<span lang=EN-US>reset</span>就会被置位。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若<span lang=EN-US>reset</span>真的被置位了，就立刻去执行<span
lang=EN-US>do_fd_request()</span>中的复位处理代码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>337</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>338</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<u><span
style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>339</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>340</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>341</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>342</span></u><span
lang=EN-US> <b><i>&nbsp;* Special case - used after a unexpected interrupt (or
reset)</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>343</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; * </span>特殊情况<span
lang=EN-US> - </span>用于意外中断（或复位）处理后。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp; */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软驱重新校正中断调用函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先发送检测中断状态命令（无参数），如果返回结果表明出错，则置复位标志。否则重新</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>校正标志清零。然后再次执行软盘请求项处理函数作相应操作。</p>

<p class=a><u><span lang=EN-US style='color:blue'>344</span></u><span
lang=EN-US> static void <u><span style='color:blue'>recal_interrupt</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>345</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>346</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SENSEI</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送检测中断状态命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>347</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>result</span></u>()!=2 || (<u><span style='color:blue'>ST0</span></u>
&amp; 0xE0) == 0x60) // </span>如果返回结果字节数不等于<span lang=EN-US>2</span>或命令</p>

<p class=a><u><span lang=EN-US style='color:blue'>348</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>reset</span></u> = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>异常结束，则置复位标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>349</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>350</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>recalibrate</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>否则复位重新校正标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>351</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>do_fd_request</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>作相应处理。</p>

<p class=a><u><span lang=EN-US style='color:blue'>352</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>353</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>意外软盘中断请求引发的软盘中断处理程序中调用的函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先发送检测中断状态命令（无参数），如果返回结果表明出错，则置复位标志，否则置重新</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>校正标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>354</span></u><span
lang=EN-US> void <u><span style='color:blue'>unexpected_floppy_interrupt</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>355</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>356</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SENSEI</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送检测中断状态命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>357</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>result</span></u>()!=2 || (<u><span style='color:blue'>ST0</span></u>
&amp; 0xE0) == 0x60) // </span>如果返回结果字节数不等于<span lang=EN-US>2</span>或命令</p>

<p class=a><u><span lang=EN-US style='color:blue'>358</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>reset</span></u> = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>异常结束，则置复位标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>359</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>360</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>recalibrate</span></u> = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span>否则置重新校正标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>361</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>362</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘重新校正处理函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>向软盘控制器<span
lang=EN-US>FDC</span>发送重新校正命令和参数，并复位重新校正标志。当软盘控制器执行完</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>重新校正命令就会再其引发的软盘中断中调用<span
lang=EN-US>recal_interrupt()</span>函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>363</span></u><span
lang=EN-US> static void <u><span style='color:blue'>recalibrate_floppy</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>364</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>365</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>recalibrate</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>复位重新校正标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>366</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>current_track</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>当前磁道号归零。</p>

<p class=a><u><span lang=EN-US style='color:blue'>367</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_floppy = <u><span
style='color:blue'>recal_interrupt</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>指向重新校正中断调用的<span lang=EN-US>C</span>函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>368</span></u><span
lang=EN-US>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_RECALIBRATE</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>命令：重新校正。</p>

<p class=a><u><span lang=EN-US style='color:blue'>369</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>head</span></u>&lt;&lt;2
| <u><span style='color:blue'>current_drive</span></u>);&nbsp;&nbsp;&nbsp; // </span>参数：磁头号<span
lang=EN-US> + </span>当前驱动器号。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>若上面任何一个<span
lang=EN-US>output_byte()</span>操作执行出错，则复位标志<span lang=EN-US>reset</span>就会被置位。因此这里</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>我们需要检测一下<span
lang=EN-US>reset</span>标志。若<span lang=EN-US>reset</span>真的被置位了，就立刻去执行<span
lang=EN-US>do_fd_request()</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>中的复位处理代码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>370</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>371</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>do_fd_request</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>372</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>373</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘控制器<span
lang=EN-US>FDC</span>复位中断调用函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数会在向控制器发送了复位操作命令后引发的软盘中断处理程序中被调用。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先发送检测中断状态命令（无参数），然后读出返回的结果字节。接着发送设定软驱</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>参数命令和相关参数，最后再次调用请求项处理函数<span
lang=EN-US>do_fd_request() </span>去执行重新校正</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>操作。但由于执行<span
lang=EN-US>output_byte() </span>函数出错时复位标志又会被置位，因此也可能再次去</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>执行复位处理。</p>

<p class=a><u><span lang=EN-US style='color:blue'>374</span></u><span
lang=EN-US> static void <u><span style='color:blue'>reset_interrupt</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>375</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>376</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SENSEI</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送检测中断状态命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>377</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void) <u><span
style='color:blue'>result</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>读取命令执行结果字节。</p>

<p class=a><u><span lang=EN-US style='color:blue'>378</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>FD_SPECIFY</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>发送设定软驱参数命令。</p>

<p class=a><u><span lang=EN-US style='color:blue'>379</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(<u><span style='color:blue'>cur_spec1</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><i>/*
hut etc */</i></b>&nbsp; // </span>发送参数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>380</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>output_byte</span></u>(6);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b><i>/*
Head load time =6ms, DMA */</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>381</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>do_fd_request</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>调用执行软盘请求。</p>

<p class=a><u><span lang=EN-US style='color:blue'>382</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>383</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>384</span></u><span
lang=EN-US> <b><i>/*</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>385</span></u><span
lang=EN-US> <b><i>&nbsp;* reset is done by pulling bit 2 of DOR low for a
while.</i></b></span></p>

<p class=a><u><span lang=EN-US style='color:blue'>386</span></u><span
lang=EN-US> <b><i>&nbsp;*/</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* FDC</span>复位是通过将数字输出寄存器<span
lang=EN-US>(DOR)</span>位<span lang=EN-US>2</span>置<span lang=EN-US>0</span>一会儿实现的<span
lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>复位软盘控制器。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数首先设置参数和标志，把复位标志清<span
lang=EN-US>0</span>，然后把软驱变量<span lang=EN-US>cur_spec1</span>和<span lang=EN-US>cur_rate</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>置为无效。因为复位操作后，这两个参数就需要重新设置。接着设置需要重新校正标志，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>并设置<span lang=EN-US>FDC</span>执行复位操作后引发的软盘中断中调用的<span
lang=EN-US>C</span>函数<span lang=EN-US>reset_interrupt()</span>。最后</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>把<span lang=EN-US>DOR</span>寄存器位<span
lang=EN-US>2</span>置<span lang=EN-US>0</span>一会儿以对软驱执行复位操作。当前数字输出寄存器<span
lang=EN-US>DOR</span>的位<span lang=EN-US>2</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>是启动<span lang=EN-US>/</span>复位软驱位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>387</span></u><span
lang=EN-US> static void <u><span style='color:blue'>reset_floppy</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>388</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>389</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>390</span></u><span
lang=EN-US> </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>391</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>reset</span></u> = 0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>复位标志置<span lang=EN-US>0</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>392</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>cur_spec1</span></u> = -1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>使无效。</p>

<p class=a><u><span lang=EN-US style='color:blue'>393</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>cur_rate</span></u> = -1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>394</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>recalibrate</span></u> = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>重新校正标志置位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>395</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>printk</span></u>(<i>&quot;Reset-floppy called\n\r&quot;</i>);&nbsp;&nbsp;&nbsp;
// </span>显示执行软盘复位操作信息。</p>

<p class=a><u><span lang=EN-US style='color:blue'>396</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>cli</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>关中断。</p>

<p class=a><u><span lang=EN-US style='color:blue'>397</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_floppy = <u><span
style='color:blue'>reset_interrupt</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>设置在中断处理程序中调用的函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>398</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>outb_p</span></u>(<u><span style='color:blue'>current_DOR</span></u>
&amp; ~0x04,<u><span style='color:blue'>FD_DOR</span></u>);&nbsp;&nbsp; // </span>对软盘控制器<span
lang=EN-US>FDC</span>执行复位操作。</p>

<p class=a><u><span lang=EN-US style='color:blue'>399</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=0 ; i&lt;100
; i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>空操作，延迟。</p>

<p class=a><u><span lang=EN-US style='color:blue'>400</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
__asm__(<i>&quot;nop&quot;</i>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>401</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>outb</span></u>(<u><span style='color:blue'>current_DOR</span></u>,<u><span
style='color:blue'>FD_DOR</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>再启动软盘控制器。</p>

<p class=a><u><span lang=EN-US style='color:blue'>402</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sti</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>开中断。</p>

<p class=a><u><span lang=EN-US style='color:blue'>403</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>404</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软驱启动定时中断调用函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在执行一个请求项要求的操作之前，为了等待指定软驱马达旋转起来到达正常的工作转速，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // do_fd_request()</span>函数为准备好的当前请求项添加了一个延时定时器。本函数即是该定时器</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>到期时调用的函数。它首先检查数字输出寄存器<span
lang=EN-US>(DOR)</span>，使其选择当前指定的驱动器。然后</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>调用执行软盘读写传输函数<span
lang=EN-US>transfer()</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>405</span></u><span
lang=EN-US> static void <u><span style='color:blue'>floppy_on_interrupt</span></u>(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// floppy_on() interrupt</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>406</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>407</span></u><span
lang=EN-US> <b><i>/* We cannot do a floppy-select, as that might sleep. We just
force it */</i></b></span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; /* </span>我们不能任意设置选择的软驱，因为这可能会引起进程睡眠。我们只是迫使它自己选择<span
lang=EN-US> */</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>如果当前驱动器号与数字输出寄存器<span
lang=EN-US>DOR</span>中的不同，则需要重新设置<span lang=EN-US>DOR</span>为当前驱动器。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在向数字输出寄存器输出当前<span
lang=EN-US>DOR</span>以后，使用定时器延迟<span lang=EN-US>2</span>个滴答时间，以让命令得到执</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>行。然后调用软盘读写传输函数<span
lang=EN-US>transfer()</span>。若当前驱动器与<span lang=EN-US>DOR</span>中的相符，那么就可以</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>直接调用软盘读写传输函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>408</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>selected</span></u> = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>置已选定当前驱动器标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>409</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>current_drive</span></u> != (<u><span style='color:blue'>current_DOR</span></u>
&amp; 3)) {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>410</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>current_DOR</span></u> &amp;= 0xFC;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>411</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>current_DOR</span></u> |= <u><span
style='color:blue'>current_drive</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>412</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>outb</span></u>(<u><span style='color:blue'>current_DOR</span></u>,<u><span
style='color:blue'>FD_DOR</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span>向数字输出寄存器输出当前<span
lang=EN-US>DOR</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>413</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>add_timer</span></u>(2,&amp;<u><span
style='color:blue'>transfer</span></u>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>添加定时器并执行传输函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>414</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>415</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>transfer</span></u>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>执行软盘读写传输函数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>416</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>417</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘读写请求项处理函数。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>该函数是软盘驱动程序中最主要的函数。主要作用是：①处理有复位标志或重新校正标志置</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>位情况；②利用请求项中的设备号计算取得请求项指定软驱的参数块；③利用内河定时器启</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>动软盘读<span lang=EN-US>/</span>写操作。</p>

<p class=a><u><span lang=EN-US style='color:blue'>418</span></u><span
lang=EN-US> void <u><span style='color:blue'>do_fd_request</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>419</span></u><span
lang=EN-US> {</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>420</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int block;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>421</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>首先检查是否有复位标志或重新校正标志置位，若有则本函数仅执行相关标志的处理功能</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>后就返回。如果复位标志已置位，则执行软盘复位操作并返回。如果重新校正标志已置位，</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>则执行软盘重新校正操作并返回。</p>

<p class=a><u><span lang=EN-US style='color:blue'>422</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>seek</span></u> = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>清寻道标志。</p>

<p class=a><u><span lang=EN-US style='color:blue'>423</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>reset</span></u>) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>复位标志已置位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>424</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>reset_floppy</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>425</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>426</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>427</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>recalibrate</span></u>) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>重新校正标志已置位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>428</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>recalibrate_floppy</span></u>();</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>429</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>430</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>本函数的真正功能从这里开始。首先利用<span
lang=EN-US>blk.h</span>文件中的<span lang=EN-US>INIT_REQUEST</span>宏来检测请求项的</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>合法性，如果已没有请求项则退出（参见<span
lang=EN-US>blk.h,127</span>）。然后利用请求项中的设备号取得请</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>求项指定软驱的参数块。这个参数块将在下面用于设置软盘操作使用的全局变量参数块（参</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>见<span lang=EN-US>112
- 122</span>行）。请求项设备号中的软盘类型 <span lang=EN-US>(MINOR(CURRENT-&gt;dev)&gt;&gt;2) </span>被用作磁盘类</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>型数组<span lang=EN-US>floppy_type[]</span>的索引值来取得指定软驱的参数块。</p>

<p class=a><u><span lang=EN-US style='color:blue'>431</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>INIT_REQUEST</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>432</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>floppy</span></u> = (<u><span style='color:blue'>MINOR</span></u>(<u><span
style='color:blue'>CURRENT</span></u>-&gt;dev)&gt;&gt;2) + <u><span
style='color:blue'>floppy_type</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>下面开始设置<span
lang=EN-US>112--122</span>行上的全局变量值。如果当前驱动器号<span lang=EN-US>current_drive</span>不是请求项</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>中指定的驱动器号，则置标志<span
lang=EN-US>seek</span>，表示在执行读<span lang=EN-US>/</span>写操作之前需要先让驱动器执行寻道处</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>理。然后把当前驱动器号设置为请求项中指定的驱动器号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>433</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>current_drive</span></u> != <u><span style='color:blue'>CURRENT_DEV</span></u>)&nbsp;&nbsp;
// CURRENT_DEV</span>是请求项中指定的软驱号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>434</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>seek</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>435</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>current_drive</span></u> = <u><span style='color:blue'>CURRENT_DEV</span></u>;</span></p>

<p class=a><span lang=EN-US>&nbsp;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>设置读写起始扇区<span
lang=EN-US>block</span>。因为每次读写是以块为单位（<span lang=EN-US>1</span>块为<span
lang=EN-US>2</span>个扇区），所以起始扇区</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>需要起码比磁盘总扇区数小<span
lang=EN-US>2</span>个扇区。否则说明这个请求项参数无效，结束该次软盘请求项</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>去执行下一个请求项。</p>

<p class=a><u><span lang=EN-US style='color:blue'>436</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block = <u><span
style='color:blue'>CURRENT</span></u>-&gt;<u><span style='color:blue'>sector</span></u>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>取当前软盘请求项中起始扇区号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>437</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (block+2 &gt; <u><span
style='color:blue'>floppy</span></u>-&gt;size) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>如果<span lang=EN-US>block + 2</span>大于磁盘扇区总数，</p>

<p class=a><u><span lang=EN-US style='color:blue'>438</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>end_request</span></u>(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>则结束本次软盘请求项。</p>

<p class=a><u><span lang=EN-US style='color:blue'>439</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
goto repeat;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>440</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>再求对应在磁道上的扇区号、磁头号、磁道号、搜寻磁道号（对于软驱读不同格式的盘）。</p>

<p class=a><u><span lang=EN-US style='color:blue'>441</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sector</span></u> = block % <u><span style='color:blue'>floppy</span></u>-&gt;sect;&nbsp;&nbsp;
// </span>起始扇区对每磁道扇区数取模，得磁道上扇区号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>442</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block /= <u><span
style='color:blue'>floppy</span></u>-&gt;sect;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>起始扇区对每磁道扇区数取整，得起始磁道数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>443</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>head</span></u> = block % <u><span style='color:blue'>floppy</span></u>-&gt;<u><span
style='color:blue'>head</span></u>;&nbsp;&nbsp;&nbsp;&nbsp; // </span>起始磁道数对磁头数取模，得操作的磁头号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>444</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>track</span></u> = block / <u><span style='color:blue'>floppy</span></u>-&gt;<u><span
style='color:blue'>head</span></u>;&nbsp;&nbsp;&nbsp; // </span>起始磁道数对磁头数取整，得操作的磁道号。</p>

<p class=a><u><span lang=EN-US style='color:blue'>445</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>seek_track</span></u> = <u><span style='color:blue'>track</span></u>
&lt;&lt; <u><span style='color:blue'>floppy</span></u>-&gt;stretch; // </span>相应于软驱中盘类型进行调整，得寻道号。</p>

<p class=a><span lang=EN-US>&nbsp;</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>再看看是否还需要首先执行寻道操作。如果寻道号与当前磁头所在磁道号不同，则需要进行</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>寻道操作，于是置需要寻道标志<span
lang=EN-US>seek</span>。最后我们设置执行的软盘命令<span lang=EN-US>command</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>446</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>seek_track</span></u> != <u><span style='color:blue'>current_track</span></u>)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>447</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>seek</span></u> = 1;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>448</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>sector</span></u>++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>磁盘上实际扇区计数是从<span lang=EN-US>1</span>算起。</p>

<p class=a><u><span lang=EN-US style='color:blue'>449</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (<u><span
style='color:blue'>CURRENT</span></u>-&gt;cmd == <u><span style='color:blue'>READ</span></u>)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// </span>如果请求项是读操作，则置读命令码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>450</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>command</span></u> = <u><span style='color:blue'>FD_READ</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>451</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (<u><span
style='color:blue'>CURRENT</span></u>-&gt;cmd == <u><span style='color:blue'>WRITE</span></u>)&nbsp;
// </span>如果请求项是写操作，则置写命令码。</p>

<p class=a><u><span lang=EN-US style='color:blue'>452</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>command</span></u> = <u><span style='color:blue'>FD_WRITE</span></u>;</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>453</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>454</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<u><span style='color:blue'>panic</span></u>(<i>&quot;do_fd_request: unknown
command&quot;</i>);</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>在上面设置好<span
lang=EN-US> 112--122</span>行上所有全局变量值之后，我们可以开始执行请求项操作了。该操</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>作利用定时器来启动。因为为了能对软驱进行读写操作，需要首先启动驱动器马达并达到正</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>常运转速度。而这需要一定的时间。因此这里利用
<span lang=EN-US>ticks_to_floppy_on() </span>来计算启动延时</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>时间，然后使用该延时设定一个定时器。当时间到时就调用函数<span
lang=EN-US>floppy_on_interrupt()</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>455</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>add_timer</span></u>(<u><span style='color:blue'>ticks_to_floppy_on</span></u>(<u><span
style='color:blue'>current_drive</span></u>),&amp;<u><span style='color:blue'>floppy_on_interrupt</span></u>);</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>456</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>457</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>各种类型软驱磁盘含有的数据块总数。</p>

<p class=a><u><span lang=EN-US style='color:blue'>458</span></u><span
lang=EN-US> static int <u><span style='color:blue'>floppy_sizes</span></u>[] ={</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>459</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
0,&nbsp;&nbsp; 0,&nbsp;&nbsp; 0,&nbsp;&nbsp; 0,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>460</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 360, 360
,360, 360,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>461</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1200,1200,1200,1200,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>462</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 360, 360,
360, 360,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>463</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 720, 720,
720, 720,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>464</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 360, 360,
360, 360,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>465</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 720, 720,
720, 720,</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>466</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1440,1440,1440,1440</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>467</span></u><span
lang=EN-US> };</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>468</span></u><span
lang=EN-US> </span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; //// </span>软盘系统初始化。</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>设置软盘块设备请求项的处理函数<span
lang=EN-US>do_fd_request()</span>，并设置软盘中断门（<span lang=EN-US>int 0x26</span>，对应</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>硬件中断请求信号<span
lang=EN-US>IRQ6</span>）。 然后取消对该中断信号的屏蔽，以允许软盘控制器<span lang=EN-US>FDC</span>发送中</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>断请求信号。中断描述符表<span
lang=EN-US>IDT</span>中陷阱门描述符设置宏<span lang=EN-US>set_trap_gate()</span>定义在头文件</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // include/asm/system.h</span>中。</p>

<p class=a><u><span lang=EN-US style='color:blue'>469</span></u><span
lang=EN-US> void <u><span style='color:blue'>floppy_init</span></u>(void)</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>470</span></u><span
lang=EN-US> {</span></p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>设置软盘中断门描述符。<span
lang=EN-US>floppy_interrupt</span>（<span lang=EN-US>kernel/sys_call.s</span>，<span
lang=EN-US>267</span>行）是其中断处理</p>

<p class=a><span lang=EN-US>&nbsp;&nbsp;&nbsp; // </span>过程。中断号为<span
lang=EN-US>int 0x26</span>（<span lang=EN-US>38</span>），对应<span
 lang=EN-US>8259A</span>芯片中断请求信号<span lang=EN-US>IRQ6</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>471</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>blk_size</span></u>[<u><span style='color:blue'>MAJOR_NR</span></u>]
= <u><span style='color:blue'>floppy_sizes</span></u>; </span></p>

<p class=a><u><span lang=EN-US style='color:blue'>472</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>blk_dev</span></u>[<u><span style='color:blue'>MAJOR_NR</span></u>].request_fn
= <u><span style='color:blue'>DEVICE_REQUEST</span></u>;&nbsp; // = do_fd_request()</span>。</p>

<p class=a><u><span lang=EN-US style='color:blue'>473</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>set_trap_gate</span></u>(0x26,&amp;<u><span
style='color:blue'>floppy_interrupt</span></u>);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>设置陷阱门描述符。</p>

<p class=a><u><span lang=EN-US style='color:blue'>474</span></u><span
lang=EN-US>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <u><span
style='color:blue'>outb</span></u>(<u><span style='color:blue'>inb_p</span></u>(0x21)&amp;~0x40,0x21);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
</span>复位软盘中断请求屏蔽位。</p>

<p class=a><u><span lang=EN-US style='color:blue'>475</span></u><span
lang=EN-US> }</span></p>

<p class=a><u><span lang=EN-US style='color:blue'>476</span></u><span
lang=EN-US> </span></p>

<div class=a align=center style='text-align:center'><span lang=EN-US>

<hr size=4 width="100%" align=center>

</span></div>

<p class=MsoNormal><span lang=EN-US>&nbsp;</span></p>

</div>

</body>

</html>
